package com.jjsc.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jjsc.cart.api.RemoteCartService;
import com.jjsc.cart.api.domain.CartInfo;
import com.jjsc.client.api.RemoteUserAddressService;
import com.jjsc.client.api.domain.UserAddress;
import com.jjsc.common.core.constant.SecurityConstants;
import com.jjsc.common.core.context.SecurityContextHolder;
import com.jjsc.common.core.domain.R;
import com.jjsc.common.core.exception.ServiceException;
import com.jjsc.common.core.utils.StringUtils;
import com.jjsc.order.domain.OrderForm;
import com.jjsc.order.domain.OrderInfo;
import com.jjsc.order.domain.OrderItem;
import com.jjsc.order.domain.CheckVo;
import com.jjsc.order.mapper.OrderItemMapper;
import com.jjsc.order.service.OrderInfoService;
import com.jjsc.order.mapper.OrderInfoMapper;
import com.jjsc.product.api.RemoteProductService;
import com.jjsc.product.api.domain.ProductSku;
import com.jjsc.product.api.domain.skuPriceVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author 41254
 * @description 针对表【order_info(订单)】的数据库操作Service实现
 * @createDate 2025-10-24 17:16:23
 */
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo>
        implements OrderInfoService {
    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private RemoteCartService remoteCartService;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RemoteProductService remoteProductService;
    @Autowired
    private RemoteUserAddressService remoteUserAddressService;

    /**
     * 查询订单列表列表
     *
     * @param orderInfo 订单列表
     * @return 订单列表
     */
    @Override
    public List<OrderInfo> selectOrderInfoList(OrderInfo orderInfo) {
        return orderInfoMapper.selectOrderInfoList(orderInfo);
    }

    /**
     * 根据id查询订单详情
     *
     * @param id 订单列表id
     * @return 订单列表
     */
    @Override
    public OrderInfo selectOrderInfoById(Long id) {
        OrderInfo orderInfo = orderInfoMapper.selectById(id);
        List<OrderItem> orderItems = orderItemMapper.selectList(
                new LambdaQueryWrapper<OrderItem>()
                        .eq(OrderItem::getOrderId, id));
        orderInfo.setOrderItemList(orderItems);
        return orderInfo;
    }

    @Override
    public List<OrderInfo> selectUserOrderInfoList(Integer orderStatus) {
        // 获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();

        List<OrderInfo> orderInfoList = baseMapper.selectUserOrderInfoList(userId, orderStatus);
        if (!CollectionUtils.isEmpty(orderInfoList)) {
            List<Long> orderIdList = orderInfoList.stream().map(OrderInfo::getId).collect(Collectors.toList());
            List<OrderItem> orderDetailList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>().in(OrderItem::getOrderId, orderIdList));
            Map<Long, List<OrderItem>> orderIdToOrderItemListMap = orderDetailList.stream().collect(Collectors.groupingBy(OrderItem::getOrderId));
            orderInfoList.forEach(item -> {
                item.setOrderItemList(orderIdToOrderItemListMap.get(item.getId()));
            });
        }
        return orderInfoList;
    }

    @Override
    public CheckVo buy(Long skuId) {
        CheckVo checkVo = new CheckVo();
        ProductSku productSku = remoteProductService.getProductSku(skuId, SecurityConstants.INNER).getData();
        List<OrderItem> orderItems = new ArrayList<>();
        OrderItem orderItem = new OrderItem();

        orderItem.setSkuId(productSku.getId());
        orderItem.setSkuName(productSku.getSkuName());
        orderItem.setThumbImg(productSku.getThumbImg());
        orderItem.setSkuNum(1);
        // 实时获取sku价格
        skuPriceVo skuPriceVo = remoteProductService.getSkuPrice(skuId, SecurityConstants.INNER).getData();
        orderItem.setSkuPrice(skuPriceVo.getPrice());
        orderItems.add(orderItem);


        checkVo.setOrderItemList(orderItems);
        checkVo.setTotalAmount(skuPriceVo.getPrice());
        checkVo.setTradeNo(this.generateTradeNo(SecurityContextHolder.getUserId()));
        checkVo.setIsBuyNow(true);

        return checkVo;
    }

    /**
     * 订单结算
     *
     * @return 订单交易数据
     */
    @Override
    public CheckVo orderTradeData() {
        Long userId = SecurityContextHolder.getUserId();
        //Long userId = 101L;
        R<List<CartInfo>> result = remoteCartService.getCartCheckedList(userId, SecurityConstants.INNER);
        if (R.FAIL == result.getCode()) {
            throw new RuntimeException(result.getMsg());
        }
        List<CartInfo> cartInfoList = result.getData();
        List<OrderItem> orderItemList = null;
        BigDecimal totalAmount = new BigDecimal(0);
        if (CollectionUtils.isEmpty(cartInfoList)) {
            throw new RuntimeException("购物车没有选中商品");
        } else {
            orderItemList = cartInfoList.stream().map(cartInfo -> {
                OrderItem orderItem = new OrderItem();
                BeanUtils.copyProperties(cartInfo, orderItem);
                return orderItem;
            }).collect(Collectors.toList());
            for (OrderItem orderItem : orderItemList) {
                totalAmount = totalAmount.add(orderItem.getSkuPrice().multiply(new BigDecimal(orderItem.getSkuNum())));
            }
        }
        CheckVo checkVo = new CheckVo();
        checkVo.setIsBuyNow(false);
        checkVo.setTotalAmount(totalAmount);
        checkVo.setOrderItemList(orderItemList);
        checkVo.setTradeNo(generateTradeNo(userId));
        return checkVo;
    }


    /**
     * 提交订单
     *
     * @param orderForm
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long submitOrder(OrderForm orderForm) {
        Long userId = SecurityContextHolder.getUserId();
        //验证用户是否通过浏览器回退进行重复提交订单
        Boolean flag = this.checkTradeNo(userId.toString(), orderForm.getTradeNo());
        if (!flag) {
            throw new ServiceException("订单已提交,请勿重复提交订单");
        }
        this.deleteTradeNo(userId.toString());
        //判断购物项
        List<OrderItem> orderItemList = orderForm.getOrderItemList();
        if (CollectionUtils.isEmpty(orderItemList)) {
            throw new ServiceException("请求不合法");
        }
        //订单校验
        List<Long> skuIdList = orderItemList.stream().map(OrderItem::getSkuId).collect(Collectors.toList());
        R<List<skuPriceVo>> skuPriceResult = remoteProductService.getSkuPriceList(skuIdList, SecurityConstants.INNER);
        if (R.FAIL == skuPriceResult.getCode()) {
            throw new ServiceException("批量获取商品价格失败");
        }
        List<skuPriceVo> skuPriceList = skuPriceResult.getData();
        Map<Long, BigDecimal> skuIdToPriceMap =
                skuPriceList.stream().collect(Collectors.toMap(skuPriceVo::getSkuId, skuPriceVo::getPrice));
        String priceCheckResult = "";
        for (OrderItem orderItem : orderItemList) {
            if (orderItem.getSkuPrice().compareTo(skuIdToPriceMap.get(orderItem.getSkuId())) != 0) {
                priceCheckResult += orderItem.getSkuName() + "价格有变";
            }
        }
        if (StringUtils.isNotEmpty(priceCheckResult)) {
            //更新购物车价格
            remoteCartService.updateCartPrice(userId, SecurityConstants.INNER);
            throw new ServiceException(priceCheckResult);
        }
        //下单
        Long orderId = null;
        orderId = this.saveOrder(orderForm);
        //删除购物车选项
        remoteCartService.deleteCartCheckedList(userId, SecurityConstants.INNER);
        return orderId;
    }

    /**
     * 下单
     *
     * @param orderForm
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    private Long saveOrder(OrderForm orderForm) {
        // 获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();
        String userName = SecurityContextHolder.getUserName();
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setUserId(userId);
        orderInfo.setNickName(userName);
        orderInfo.setOrderNo(orderForm.getTradeNo());
        orderInfo.setRemark(orderForm.getRemark());


        UserAddress userAddress = remoteUserAddressService.getUserAddress(orderForm.getUserAddressId(), SecurityConstants.INNER).getData();
        orderInfo.setReceiverName(userAddress.getName());
        orderInfo.setReceiverPhone(userAddress.getPhone());
        orderInfo.setReceiverTagName(userAddress.getTagName());
        orderInfo.setReceiverProvince(userAddress.getProvinceCode());
        orderInfo.setReceiverCity(userAddress.getCityCode());
        orderInfo.setReceiverDistrict(userAddress.getDistrictCode());
        orderInfo.setReceiverAddress(userAddress.getFullAddress());

        List<OrderItem> orderItemList = orderForm.getOrderItemList();
        BigDecimal totalAmount = new BigDecimal(0);
        for (OrderItem orderItem : orderItemList) {
            totalAmount = totalAmount.add(orderItem.getSkuPrice().multiply(new BigDecimal(orderItem.getSkuNum())));
        }
        orderInfo.setTotalAmount(totalAmount);
        //orderInfo.setCouponAmount(new BigDecimal(0));
        orderInfo.setFeightFee(orderForm.getFeightFee());
        orderInfo.setOrderStatus(0);
        baseMapper.insert(orderInfo);

        //保存订单明细
        for (OrderItem orderItem : orderItemList) {
            orderItem.setOrderId(orderInfo.getId());
            orderItemMapper.insert(orderItem);
        }
        return orderInfo.getId();

    }

    /**
     * 验证页面提交流水号是否有效
     *
     * @param userId
     * @param tradeNo
     * @return
     */
    private Boolean checkTradeNo(String userId, String tradeNo) {
        String userTradeKey = "user:tradeNo:" + userId;
        String redisTradeNo = (String) redisTemplate.opsForValue().get(userTradeKey);
        return tradeNo.equals(redisTradeNo);
    }


    /**
     * 删除流水号
     *
     * @param userId
     */
    private void deleteTradeNo(String userId) {
        String userTradeKey = "user:tradeNo:" + userId;
        redisTemplate.delete(userTradeKey);
    }

    /**
     * 渲染订单确认页面-生成用户流水号
     *
     * @param userId
     * @return
     */
    private String generateTradeNo(Long userId) {
        //1.构建流水号Key
        String userTradeKey = "user:tradeNo:" + userId;
        //2.构建流水号value
        String tradeNo = UUID.randomUUID().toString().replaceAll("-", "");
        //3.将流水号存入Redis 暂存5分钟
        redisTemplate.opsForValue().set(userTradeKey, tradeNo, 5, TimeUnit.MINUTES);
        return tradeNo;
    }
}




